//产看内存
use kernel32;
use winapi;
use winapi::{
    DWORD, //类型在rust中为u32
    HANDLE,
    LPSYSTEM_INFO,                       //指向system_info的长指针
    LPVOID, //多个内部api使用的没有关联类型的指针类型(可以接受任何类型的指针)。在rust中std::os::raw::c_void定义了void指针。
    MEMORY_BASIC_INFORMATION as MEMINFO, //win内部定义的一些结构体
    //一个HANDLE(句柄)是在windows中指向一些不透资源的指针。
    PVOID,  //P:表示指针，LP表示长指针
    SIZE_T, //U64对应计算机的usize
    SYSTEM_INFO,
};
fn main() {
    //放unsafe中解析
    let this_pid: DWORD;
    let this_proc: HANDLE;
    let min_addr: LPVOID;
    let max_addr: LPVOID;
    let mut base_addr: PVOID;
    let mut proc_info: SYSTEM_INFO;
    let mut mem_info: MEMINFO;
    const MEMINFO_SIZE: usize = std::mem::size_of::<MEMINFO>();

    //保证内存初始化
    unsafe {
        base_addr = std::mem::zeroed();
        proc_info = std::mem::zeroed();
        mem_info = std::mem::zeroed();
    }
    //发起系统调用
    unsafe {
        this_pid = kernel32::GetCurrentProcessId();
        this_proc = kernel32::GetCurrentProcess();
        kernel32::GetSystemInfo(&mut proc_info as LPSYSTEM_INFO);
    }

    //重命名变量
    min_addr = proc_info.lpMinimumApplicationAddress;
    max_addr = proc_info.lpMaximumApplicationAddress;

    println!("{:?} @ {:p}", this_pid, this_proc);
    println!("{:?}", proc_info);
    println!("min: {:p}, max: {:p}", min_addr, max_addr);

    //扫描地址空间
    loop {
        let rc: SIZE_T = unsafe {
            //系统调用，提供这个真在运行的程序的内存地址空间中一个指定段的信息，起始位置地址为base_addr
            kernel32::VirtualQueryEx(this_proc, base_addr, &mut mem_info, MEMINFO_SIZE as SIZE_T)
        };
        if rc == 0 {
            break;
        }
        println!("{:?}", mem_info);
        base_addr = ((base_addr as u64) + mem_info.RegionSize) as PVOID;
    }
}
